package com.bringspring.oauth.controller;

import cn.hutool.core.util.ObjectUtil;
import com.bringspring.common.base.ActionResult;
import com.bringspring.common.base.NoDataSourceBind;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.config.ConfigValueUtil;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.database.data.DataSourceContextHolder;
import com.bringspring.common.model.login.BaseSystemInfo;
import com.bringspring.common.model.login.LoginForm;
import com.bringspring.common.model.login.LoginVO;
import com.bringspring.common.util.*;
import com.bringspring.system.base.exception.BaseException;
import com.bringspring.system.base.exception.LoginException;
import com.bringspring.oauth.model.LoginModel;
import com.bringspring.oauth.model.PcUserVO;
import com.bringspring.oauth.service.LoginService;
import com.bringspring.system.base.model.systemconfig.QyChatModel;
import com.bringspring.system.base.service.SysConfigService;
import com.bringspring.system.permission.entity.UserEntity;
import com.bringspring.system.permission.exception.PermissionException;
import com.bringspring.system.permission.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * 登录控制器
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月26日 上午9:18
 */
@Api(tags = "登陆数据", value = "oauth")
@Slf4j
@RestController
@RequestMapping("/api/oauth")
public class LoginController {

    @Autowired
    private UserService userService;
    @Autowired
    private TokenEndpoint tokenEndpoint;
    @Autowired
    private LoginService loginService;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private RedisUtil redisUtil;


    @ApiOperation("登陆")
    @PostMapping(value = "/Login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ActionResult<LoginVO> Login(Principal principal, @RequestParam Map<String, String> parameters) throws LoginException {
        OAuth2AccessToken oAuth2AccessToken;

        try {
            oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        } catch (Exception e) {
            e.printStackTrace();
            throw new LoginException(e.getMessage());
        }
        //获取主题
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(oAuth2AccessToken.getTokenType() + " " + oAuth2AccessToken.getValue());
        return ActionResult.success(loginVO);
    }

    /**
     * 验证密码
     *
     * @return
     */
    @ApiOperation("锁屏解锁登录")
    @PostMapping("/LockScreen")
    public ActionResult lockScreen(@RequestBody LoginForm loginForm) throws LoginException, PermissionException {
        UserEntity userEntity = userService.getUserByAccount(loginForm.getAccount());
        if (!Md5Util.getStringMd5(loginForm.getPassword().toLowerCase() + userEntity.getSecretkey().toLowerCase()).equals(userEntity.getPassword())) {
            throw new LoginException(MsgCode.LOG101.get());
        }
        return ActionResult.success(MsgCode.SU017.get());
    }

    /**
     * 登录注销
     *
     * @return
     */
    @ApiOperation("退出")
    @GetMapping("/Logout")
    public ActionResult logout() {
        if (ObjectUtil.isNotEmpty(userProvider.get())) {
            if (Objects.nonNull(sysConfigService.getSysInfo()) && "1".equals(String.valueOf(sysConfigService.getSysInfo().getSingleLogin()))) {
                userProvider.removeCurrent();
            } else {
                String id = userProvider.get().getId();
                redisUtil.remove(id);
            }
        }
        return ActionResult.success(MsgCode.LOG002.get());
    }

    /**
     * 获取用户登录信息
     *
     * @return
     */
    @ApiOperation("获取用户登录信息")
    @GetMapping("/CurrentUser")
    public ActionResult<PcUserVO> currentUser(String type,String applicationId) throws LoginException {
        PcUserVO pcUserVO = loginService.getCurrentUser(type,applicationId);
        if (pcUserVO == null) {
            throw new LoginException(MsgCode.LOG001.get());
        }
        return ActionResult.success(pcUserVO);
    }

    /**
     * 图形验证码
     *
     * @return
     */
    @NoDataSourceBind()
    @ApiOperation("图形验证码")
    @GetMapping("/ImageCode/{codeLength}/{timestamp}")
    public void imageCode(@PathVariable("codeLength") Integer codeLength, @PathVariable("timestamp") String timestamp) {
        DownUtil.downCode(codeLength);
        redisUtil.insert(timestamp, ServletUtils.getSession().getAttribute(CodeUtil.RANDOMCODEKEY), 300);
    }

    /**
     * 判断是否需要验证码
     *
     * @param account 账号
     */
    @NoDataSourceBind()
    @ApiOperation("判断是否需要验证码")
    @GetMapping("/getConfig/{account}")
    public ActionResult check(@PathVariable("account") String account) throws LoginException {
        LoginModel loginModel = new LoginModel();
        if (Boolean.parseBoolean(configValueUtil.getMultiTenancy())) {
            LoginForm loginForm = new LoginForm();
            loginForm.setAccount(account);
            UserInfo userInfo = loginService.checkTenant(loginForm);
            //设置租户
            DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString());
        }
        // 获取配置
        BaseSystemInfo sysConfigInfo = sysConfigService.getSysInfo();
        // 是否开启验证码
        if (Objects.nonNull(sysConfigInfo) && "1".equals(String.valueOf(sysConfigInfo.getEnableVerificationCode()))) {
            loginModel.setEnableVerificationCode(1);
            Integer verificationCodeNumber = sysConfigInfo.getVerificationCodeNumber();
            loginModel.setVerificationCodeNumber(verificationCodeNumber == null ? 4 : verificationCodeNumber);
            return ActionResult.success(loginModel);
        }
        loginModel.setEnableVerificationCode(0);
        return ActionResult.success(loginModel);
    }
    /**
     * 获取企业微信配置
     */
    @NoDataSourceBind()
    @ApiOperation("获取企业微信配置")
    @GetMapping("/getQyhConfig")
    public ActionResult getQyhConfig() throws BaseException {
        // 获取配置
        List<QyChatModel> qyChatModelList = sysConfigService.getQyChatModelList();
        return ActionResult.success(qyChatModelList);
    }
}
